/*
 *  Copyright 2020, dqsjqian(Mr.Zhang).  All right reserved.
 *
 *  THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF dqsjqian(Mr.Zhang).
 *  LTD.  THE CONTENTS OF THIS FILE MAY NOT BE DISCLOSED TO THIRD
 *  PARTIES, COPIED OR DUPLICATED IN ANY FORM, IN WHOLE OR IN PART,
 *  WITHOUT THE PRIOR WRITTEN PERMISSION OF dqsjqian(Mr.Zhang).
 *
 *
 *  Edit History:
 *
 *    2020-01-12 - Created by dqsjqian(Mr.Zhang) dqsjqian@163.com
 *	Blog: https://blog.csdn.net/dqsjqian
 *	Gitee: https://gitee.com/dqsjqian
 */

#include <iostream>
using namespace std;

class AbstractClass
{
public:
    void TemplateMethod()
    {
        PrimitiveOperation1();
        cout << "TemplateMethod" << endl;
        PrimitiveOperation2();
    }

protected:
    virtual void PrimitiveOperation1()
    {
        cout << "Default Operation1" << endl;
    }

    virtual void PrimitiveOperation2()
    {
        cout << "Default Operation2" << endl;
    }
};

class ConcreteClassA : public AbstractClass
{
protected:
    virtual void PrimitiveOperation1()
    {
        cout << "ConcreteA Operation1" << endl;
    }

    virtual void PrimitiveOperation2()
    {
        cout << "ConcreteA Operation2" << endl;
    }
};

class ConcreteClassB : public AbstractClass
{
protected:
    virtual void PrimitiveOperation1()
    {
        cout << "ConcreteB Operation1" << endl;
    }

    virtual void PrimitiveOperation2()
    {
        cout << "ConcreteB Operation2" << endl;
    }
};

int main()
{
    AbstractClass* pAbstractA = new ConcreteClassA;
    pAbstractA->TemplateMethod();

    AbstractClass* pAbstractB = new ConcreteClassB;
    pAbstractB->TemplateMethod();

    if (pAbstractA) delete pAbstractA;
    if (pAbstractB) delete pAbstractB;
}